package com.Register.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.Register.context.BaseContext;
import com.Register.dto.AllCarouselsPageQueryDTO;
import com.Register.dto.CarouselDTO;
import com.Register.dto.CarouselsUpdateDTO;
import com.Register.entity.Carousel;
import com.Register.mapper.CarouselMapper;
import com.Register.result.PageResult;
import com.Register.result.Result;
import com.Register.service.CarouselService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

import static com.Register.constant.RedisConstant.*;

@Service
public class CarouselServiceImpl extends ServiceImpl<CarouselMapper, Carousel> implements CarouselService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private ObjectMapper objectMapper = new ObjectMapper();

    @Resource
    private CarouselMapper carouselMapper;
    /**
     * 管理员创建轮播图
     */
    @Override
    @Transactional
    public Result<String> createCarousel(CarouselDTO carouselDTO) throws JsonProcessingException {
        //创建轮播图对象
        Carousel carousel=Carousel.builder()
                .title(carouselDTO.getTitle())
                .imageUrl(carouselDTO.getImageUrl())
                .linkUrl(carouselDTO.getLinkUrl())
                .sortOrder(carouselDTO.getSortOrder())
                .createTime(LocalDateTime.now())
                .createUser(BaseContext.getCurrentId())
                .build();
        int size= Objects.requireNonNull(stringRedisTemplate.opsForList().size(carouselIdList)).intValue();
        if(size>=5){
            carousel.setActiveStatus(false);
            save(carousel);
            return Result.success("最多同时展示5张图片，新增加的图片请手动选择展示");
        }
        //保存到数据库
        save(carousel);
        //缓存到redis中
        stringRedisTemplate.opsForValue().set(CarouselInfo+carousel.getId(),objectMapper.writeValueAsString(carouselDTO));
        //加入到展示队列中
        stringRedisTemplate.opsForList().leftPush(carouselIdList,carousel.getId().toString());
        return Result.success("创建成功");
    }

    /**
     * 查询所有启用的轮播图
     */
    @Override
    public List<CarouselDTO> getActiveCarousels() throws JsonProcessingException {
        //直接从展示队列中读取轮播图对象,读取5张轮播图
        List<String> idList=stringRedisTemplate.opsForList().range(carouselIdList,0,4);
        //如果为空放回空值
        if(idList==null||idList.isEmpty()){
            return Collections.emptyList();
        }
        //从redis中查询轮播图对象
        List<CarouselDTO> carouselDTOList=new ArrayList<>();
        for(String id:idList){
            String cacheCarouse=stringRedisTemplate.opsForValue().get(CarouselInfo+id);
            if(cacheCarouse!=null){
                CarouselDTO carouselDTO=objectMapper.readValue(cacheCarouse,CarouselDTO.class);
                carouselDTOList.add(carouselDTO);
            }
            //没有该数据就去数据库找
            else {
                //根据条件查找
                Carousel carousel=getById(id);
                if(carousel!=null) {
                    CarouselDTO carouselDTO = CarouselDTO.builder()
                            .imageUrl(carousel.getImageUrl())
                            .title(carousel.getTitle())
                            .linkUrl(carousel.getLinkUrl())
                            .sortOrder(carousel.getSortOrder())
                            .build();
                    carouselDTOList.add(carouselDTO);
                    //缓存到redis中
                    stringRedisTemplate.opsForValue().set(CarouselInfo + carousel.getId(), objectMapper.writeValueAsString(carouselDTO));
                }
            }
        }
        // 按 sortOrder 排序
        carouselDTOList.sort(Comparator.comparingInt(CarouselDTO::getSortOrder));
        return carouselDTOList;
    }

    /**
     * 全部轮播图分页查询
     */
    @Override
    public PageResult getAllCarousels(AllCarouselsPageQueryDTO allCarouselsPageQueryDTO) {
        //构建分页条件
        Page<Carousel> page=allCarouselsPageQueryDTO.toMpPageDefaultSortByCreateTimeDesc();

        //构建查询条件
        LambdaQueryWrapper<Carousel> lambdaQueryWrapper=new LambdaQueryWrapper<>();

        lambdaQueryWrapper
                .eq(allCarouselsPageQueryDTO.getActiveStatus()!=null,Carousel::getActiveStatus,
                        allCarouselsPageQueryDTO.getActiveStatus());
        Page<Carousel> carouselPage=carouselMapper.selectPage(page,lambdaQueryWrapper);
        //总页数
        long pages = carouselPage.getPages();
        //总记录数
        long total = carouselPage.getTotal();
        //当前页数据
        List<Carousel> records = carouselPage.getRecords();

        return new PageResult(pages,total,records);
    }
    /*
    根据id查询轮播图
     */
    @Override
    public Carousel getCarouseByid(Long id) {
        return getById(id);
    }

    /*
    管理员更新轮播图
     */
    @Override
    public Result<String> updateCarouse(CarouselsUpdateDTO carouselsUpdateDTO) {
        //获取对象
        Carousel carousel=getById(carouselsUpdateDTO.getId());
        //拷贝对象设置更新
        carousel.setUpdateTime(LocalDateTime.now());
        carousel.setUpdateUser(BaseContext.getCurrentId());
        if(carouselsUpdateDTO.getDeleted()!=null&&carouselsUpdateDTO.getDeleted()==1){
            carouselMapper.deleteById(carouselsUpdateDTO.getId());
            stringRedisTemplate.opsForList().remove(carouselIdList,0,carouselsUpdateDTO.getId().toString());
            return Result.success("删除成功");
        }
        //检查更新操作是否合法
        if(carouselsUpdateDTO.getActiveStatus()!=null&& carouselsUpdateDTO.getActiveStatus()){
            int size= Objects.requireNonNull(stringRedisTemplate.opsForList().size(carouselIdList)).intValue();
            //添加到展示列表
            if(size>=5){
                return Result.error("最多同时展示5张图片");
            }
            stringRedisTemplate.opsForList().leftPush(carouselIdList,carousel.getId().toString());
        }
        //如果不展示了
        if(carouselsUpdateDTO.getActiveStatus()!=null&& !carouselsUpdateDTO.getActiveStatus()){
            //移除展示列表
            stringRedisTemplate.opsForList().remove(carouselIdList,0,carouselsUpdateDTO.getId().toString());
        }
        BeanUtil.copyProperties(carouselsUpdateDTO,carousel);
        updateById(carousel);
        //删除对应的redis缓存
        stringRedisTemplate.delete(CarouselInfo+carousel.getId());
        return Result.success("更新成功");
    }
}
